package es_ser

import (
	"context"
	"encoding/json"
	"errors"
	"github.com/olivere/elastic/v7"
	"giv-vue-blog/global"
	"giv-vue-blog/models"
	"giv-vue-blog/service/redis_ser"
	"strings"
)

func CommonList(option Option) (list []models.ArticleModel, count int, err error) {
	boolSearch := elastic.NewBoolQuery()
	// 根据title进行搜索
	if option.Key != "" {
		boolSearch.Must(
			elastic.NewMultiMatchQuery(option.Key, option.Fields...), //多个字段搜索 比如标题、简介、分类等等
		)
	}
	//根据标签搜索
	if option.Tag != "" {
		boolSearch.Must(
			elastic.NewMultiMatchQuery(option.Tag, "tags"))
	}
	//排序
	type SortField struct {
		Field     string
		Ascending bool
	}
	//排序的默认字段
	sortField := SortField{
		Field:     "created_at",
		Ascending: false, //从小到大排序 反之为从大到小
	}
	if option.Sort != "" {
		_list := strings.Split(option.Sort, " ")
		if len(_list) == 2 && (_list[1] == "desc" || _list[1] == "asc") {
			sortField.Field = _list[0]
			if _list[1] == "desc" {
				sortField.Ascending = false
			}
			if _list[1] == "asc" {
				sortField.Ascending = true
			}
		}
	}
	// 查询
	res, err := global.EsClient.
		Search(models.ArticleModel{}.Index()).
		Query(boolSearch).
		Highlight(elastic.NewHighlight().Field("title")). //文章高亮搜索
		//方法一 不显示content，它只会把这个内容在界面上渲染为空 因此采用另一种方法 在结构体中content字段后添加omit(list) 当在list时会把这个字段给去掉
		//FetchSourceContext(elastic.NewFetchSourceContext(true).Exclude("content")).
		From(option.GetForm()).
		Sort(sortField.Field, sortField.Ascending).
		Size(option.Limit).
		Do(context.Background())

	if err != nil {
		return
	}
	//统计索引个数
	count = int(res.Hits.TotalHits.Value)
	//demoList := []models.ArticleModel{}
	demoList := make([]models.ArticleModel, 0)
	diggInfo := redis_ser.NewDigg().GetInfo()
	lookInfo := redis_ser.NewArticleLook().GetInfo()
	commentInfo := redis_ser.NewComment().GetInfo()
	for _, hit := range res.Hits.Hits {
		var demo models.ArticleModel
		err = json.Unmarshal(hit.Source, &demo)
		if err != nil {
			global.Log.Error(err)
			continue
		}
		title, ok := hit.Highlight["title"]
		if ok {
			demo.Title = title[0] //高亮搜索展示
		}
		demo.ID = hit.Id
		digg := diggInfo[hit.Id]       //文章点赞量
		look := lookInfo[hit.Id]       //文章浏览量
		comment := commentInfo[hit.Id] //文章评论量
		demo.DiggCount = demo.DiggCount + digg
		demo.LookCount = demo.LookCount + look
		demo.CommentCount = demo.CommentCount + comment
		demoList = append(demoList, demo)
	}
	return demoList, count, err
}

func CommonDetail(id string) (model models.ArticleModel, err error) {
	// 查询
	res, err := global.EsClient.
		Get().
		Index(models.ArticleModel{}.Index()).Id(id).
		Do(context.Background())

	if err != nil {
		global.Log.Error(err.Error())
		return
	}
	err = json.Unmarshal(res.Source, &model)
	if err != nil {
		return
	}
	model.ID = res.Id
	model.LookCount = model.LookCount + redis_ser.NewArticleLook().Get(res.Id) //浏览量
	return
}
func CommonDetailKeyword(key string) (model models.ArticleModel, err error) {
	// 查询
	res, err := global.EsClient.
		Search().
		Index(models.ArticleModel{}.Index()).Query(elastic.NewTermsQuery("keyword", key)).
		Size(1).
		Do(context.Background())

	if err != nil {
		global.Log.Error(err.Error())
		return
	}
	if res.Hits.TotalHits.Value == 0 {
		return model, errors.New("文章不存在")
	}
	hit := res.Hits.Hits[0]
	_ = json.Unmarshal(hit.Source, &model)
	if err != nil {
		return
	}
	model.ID = hit.Id
	return
}
func ArticleUpdateCommon(id string, data map[string]any) error {
	_, err := global.EsClient.Update().
		Index(models.ArticleModel{}.Index()).
		Id(id).
		Doc(data).
		Do(context.Background())
	return err
}
